import { _decorator, Component, Node, assetManager, AssetManager } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('BundleManager')
export class BundleManager {
    private static _instance: BundleManager;
    public static get instance () {
        if (this._instance) {
            return this._instance;
        }

        this._instance = new BundleManager();
        return this._instance;
    }


    private _completeBundle: Array<string> = [];
    private _bundleResInfo: { [uuid: string]: string; } = {};

    /**
     * 获取bundle包
     * @param bundleName 
     * @returns 
     */
    public getBundle (bundleName: string) {
        return new Promise((resolve, reject) => {
            let bundle = assetManager.getBundle(bundleName);
            if (!bundle) {
                this.loadBundleNoOptions(bundleName, (err: any, bundle: AssetManager.Bundle) => {
                    if (err) {
                        console.log(err)
                        reject && reject(err)
                        return;
                    }
                    return resolve && resolve(bundle);
                })
            }

            resolve && resolve(bundle);
        })
    }


    public async getBundleByUUID (uuid: string) {
        return this.getBundle(this.getBundleNameByUUID(uuid));
    }



    /**
     * 通过uuid获取
     * @param uuid 
     * @returns 
     */
    public getBundleNameByUUID (uuid: string) {
        return this._bundleResInfo[uuid];
    }


    /**
     * 加载bundle包不设置信息
     * @param name 
     * @param completeCB 
     */
    public loadBundleNoOptions (name: string, completeCB: Function) {
        this.loadBundle(name, null, completeCB);
    }

    /**
     * 加载bundle包
     * @param name 
     * @param options 
     * @param completeCB 
     */
    public loadBundle (name: string, options: any, completeCB: Function) {
        assetManager.loadBundle(name, options, (err: any, bundle: AssetManager.Bundle) => {
            if (this._completeBundle.indexOf(name) < 0) {

                this._completeBundle.push(name);
                bundle.config.paths.forEach((value: Array<any>) => {
                    value.forEach((resInfo) => {
                        this._bundleResInfo[resInfo.uuid] = name;
                    })
                })
            }
            completeCB && completeCB(err, bundle);
        });
    }

    /**
     * 移除制定bundle包
     * @param name 
     * @returns 
     */
    public removeBundle (name: string) {

        const bundle = assetManager.getBundle(name);
        if (!bundle) {
            console.warn(`未找到${name}bundle包,或以清除`);
            return;
        }
        bundle.releaseAll();
        assetManager.removeBundle(bundle);
    }

    /**
     * 移除所有bundle包
     */
    public removeAllBundle () {
        const bundles = assetManager.bundles;
        bundles.forEach((bundle: AssetManager.Bundle, name: string) => {
            this.removeBundle(name);
        })
    }


}

